<template>
    <a-list :data-source="dataSource">
      <template #loadMore>
        <div style="text-align: center; margin-top: 15px">
          <a-button type="primary" ghost @click.stop="loadQusComment">更多评论</a-button>
        </div>
      </template>
      <template #renderItem="{ item, index }">
        <a-list-item>
          <a-comment>
            <template #actions>
              <span>
                <a-tooltip title="点赞">
                  <template v-if="item.action === 1">
                    <LikeFilled @click="like(index)" />
                  </template>
                  <template v-else>
                    <LikeOutlined @click="like(index)" />
                  </template>
                </a-tooltip>
                <span style="padding-left: 8px; cursor: auto">
                  {{ item.like }}
                </span>
              </span>
              <span>
                <a-tooltip title="踩">
                  <template v-if="item.action === 2">
                    <DislikeFilled @click="dislike(index)" />
                  </template>
                  <template v-else>
                    <DislikeOutlined @click="dislike(index)" />
                  </template>
                </a-tooltip>
                <span style="padding-left: 8px; cursor: auto">
                  {{ item.dislike }}
                </span>
              </span>
              <span @click="spanReply(index)">回复</span>
              <a-popconfirm title="确定删除吗？" ok-text="确定"  cancel-text="取消" @confirm="onDeleteComment(item.id, index)">
                <span v-if="item.canDelete">删除</span>
              </a-popconfirm>
              <span @click="spanConversation(index)">查看对话</span>
            </template>
            <template #content>
              <div><p>{{ item.content }}</p></div>
            </template>
            <template #author><a>{{ item.sender }}</a></template>
            <template #datetime>
              <span>{{ item.time }}</span>
            </template>
            <div v-if="item.showReply">
              <a-form-item>
                <a-textarea
                  v-model:value="reply"
                  :rows="2"
                  allowClear
                  :maxlength="500"
                  placeholder="写下精彩的回复吧"
                  style="width: 320px" />
              </a-form-item>
              <a-form-item>
                <a-button @click="submitReply(index)" type="primary">回复</a-button>
              </a-form-item>
            </div>
            <InnerComment
              v-if="item.showConversation"
              @reply-load-more="loadReply(index)"
              @reply-delete="onDeleteReply"
              @reply-success="submitInnerReply"
              :data-source="item.conversations"
              :loading="item.replyLoadStatus"
              :cid="item.id"
              :uname="uname"/>
          </a-comment>
        </a-list-item>
        </template>
      </a-list>
      <div>
        <a-comment>
          <template #avatar>
            <a-avatar style="background-color: #87d068">{{ uname.substring(0, 1)}}</a-avatar>
          </template>
          <template #content>
            <a-form-item>
              <a-textarea v-model:value="comment" :rows="1" allowClear :maxlength="500" />
            </a-form-item>
            <a-form-item>
              <a-button type="primary" @click="submitComment">评论</a-button>
            </a-form-item>
          </template>
        </a-comment>
      </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, watch } from 'vue'
import { Comment, Tooltip, List, Input, Button, Form, Avatar, message, Popconfirm } from 'ant-design-vue'
import { DislikeFilled, DislikeOutlined, LikeFilled, LikeOutlined } from '@ant-design/icons-vue'
import { CommentDs, createCommentDs, CommentSend, ReplySend } from '@/utils/ds'
import InnerComment from '@/components/InnerComment.vue'
import {
  addComment,
  addReply,
  getComment,
  deleteComment,
  commentLike,
  commentDislike,
  getConversation
} from '@/service'
import { formatDate, getUserID } from '@/utils/check'
import { LIKE_OP, DISLIKE_OP, NULL_OP } from '@/utils/constants'

export default defineComponent({
  name: 'SubComment',
  components: {
    InnerComment,
    AComment: Comment,
    ATooltip: Tooltip,
    DislikeFilled,
    DislikeOutlined,
    LikeOutlined,
    LikeFilled,
    AList: List,
    AListItem: List.Item,
    AButton: Button,
    ATextarea: Input.TextArea,
    AFormItem: Form.Item,
    AAvatar: Avatar,
    APopconfirm: Popconfirm
  },
  props: {
    uname: {
      type: String,
      default: 'K'
    },
    pid: {
      type: Number,
      default: 0,
      require: false
    }
  },
  setup (props) {
    const dataSource = ref<CommentDs[]>([])
    const conversations = ref<Map<number, CommentDs[]>>(new Map<number, CommentDs[]>())
    const conversationLoadCursor = ref<Map<number, number>>(new Map<number, number>())
    const commentLoadCursor = ref<Map<number, number>>(new Map<number, number>())
    const comment = ref<string>('')
    const reply = ref<string>('')
    const curUid = ref<number>(0)

    const like = (idx: number) => {
      const item = dataSource.value[idx]
      const previousAction = item.action
      if (previousAction === LIKE_OP) {
        item.like -= 1
        item.action = NULL_OP
        commentLike(item.id, 0)
        return
      }
      if (previousAction === DISLIKE_OP) {
        item.dislike -= 1
      }
      item.like += 1
      item.action = LIKE_OP
      commentLike(item.id, 1)
    }

    const dislike = (idx: number) => {
      const item = dataSource.value[idx]
      const previousAction = item.action
      if (previousAction === DISLIKE_OP) {
        item.dislike -= 1
        item.action = NULL_OP
        commentDislike(item.id, 0)
        return
      }
      if (previousAction === LIKE_OP) {
        item.like -= 1
      }
      item.dislike += 1
      item.action = DISLIKE_OP
      if (item.id > 0) {
        commentDislike(item.id, 1)
      }
    }

    const spanReply = (idx: number) => {
      const item = dataSource.value[idx]
      item.showReply = !item.showReply
    }

    const spanConversation = (idx: number) => {
      const item = dataSource.value[idx]
      const status = item.showConversation
      item.showConversation = !status
      const c = conversations.value
      if (!c.has(item.id)) {
        c.set(item.id, [])
      }
      const t = c.get(item.id)
      if (t !== undefined) {
        item.conversations = t
      }
      if (!item.initLoadReply) {
        loadReply(idx)
        item.initLoadReply = true
      }
    }

    const submitComment = () => {
      if (comment.value === '') {
        return
      }
      const cur = new Date().getTime()
      const dataSend: CommentSend = {
        pid: props.pid,
        sender: props.uname,
        content: comment.value,
        created: cur
      }
      addComment(dataSend)
        .then(response => {
          if (response.status !== 200) {
            message.warn('网络请求出错')
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            message.warn('返回出错')
            return
          }
          const c = createCommentDs()
          c.id = resp.data
          c.pid = props.pid
          c.sender = props.uname
          c.sid = curUid.value
          c.content = dataSend.content
          c.time = formatDate(new Date(cur))
          c.canDelete = true
          dataSource.value.unshift(c)
          const cursor = commentLoadCursor.value
          const offset = cursor.get(props.pid)
          if (offset === undefined) {
            cursor.set(props.pid, 1)
          } else if (offset !== -1) {
            cursor.set(props.pid, offset + 1)
          }
        })
      comment.value = ''
    }

    const onDeleteComment = (id: number, idx: number) => {
      deleteComment(id)
        .then((response) => {
          if (response.status !== 200) {
            message.info('请求出错')
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            message.info('返回出错')
            return
          }
          if (resp.data) {
            dataSource.value.splice(idx, 1)
          } else {
            message.info('删除出错')
          }
        })
    }

    const submitReply = (idx: number) => {
      if (reply.value === '') {
        return
      }
      const item = dataSource.value[idx]
      const cid = item.id
      const receiver = item.sender
      const cur = new Date().getTime()
      const dataSend: ReplySend = {
        cid: item.id,
        refId: item.id,
        sender: props.uname,
        receiver: item.sender,
        rid: item.sid,
        content: reply.value,
        created: cur
      }
      addReply(dataSend)
        .then(response => {
          if (response.status !== 200) {
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            return
          }
          const c = createCommentDs()
          c.id = resp.data
          c.cid = cid
          c.sender = props.uname
          c.content = dataSend.content
          c.time = formatDate(new Date(cur))
          c.canDelete = true
          c.receiver = receiver
          c.rid = dataSend.rid

          const cursor = conversationLoadCursor.value
          const offset = cursor.get(cid)
          if (offset === undefined) {
            cursor.set(cid, 1)
          } else if (offset === -1) {
            //
          } else {
            cursor.set(cid, offset + 1)
          }

          const conn = conversations.value
          if (!conn.has(cid)) {
            conn.set(cid, [])
          }
          const conversation = conn.get(cid)
          if (conversation !== undefined) {
            conversation.unshift(c)
          }
          if (!item.showConversation) {
            spanConversation(idx)
          }
          item.showReply = false
          reply.value = ''
        })
    }

    const submitInnerReply = (data: ReplySend, id: number) => {
      const c = createCommentDs()
      const cid = data.cid
      c.id = id
      c.cid = cid
      c.sender = props.uname
      c.content = data.content
      c.time = formatDate(new Date(data.created))
      c.canDelete = true
      c.receiver = data.receiver
      c.rid = data.rid
      if (!conversations.value.has(cid)) {
        conversations.value.set(cid, [])
      }
      const conversation = conversations.value.get(cid)
      if (conversation !== undefined) {
        conversation.unshift(c)
      }
      const cursor = conversationLoadCursor.value
      const offset = cursor.get(cid)
      if (offset === undefined) {
        cursor.set(cid, 1)
      } else if (offset !== -1) {
        cursor.set(cid, offset + 1)
      }
    }

    const loadQusComment = () => {
      const pid = props.pid
      const count = 5
      // console.log('comment:', pid)
      const cursor = commentLoadCursor.value
      let offset = cursor.get(pid)
      if (offset === undefined) {
        offset = 0
      } else if (offset === -1) {
        message.info('已经加载全部评论', 0.3)
        return
      }
      getComment(pid, offset, count)
        .then(response => {
          if (response.status !== 200) {
            message.warn('网络请求出错')
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            message.warn('返回评论出错')
            return
          }
          const data = resp.data

          data.forEach((item: any) => {
            const e = createCommentDs()
            e.id = item.id
            e.sender = item.sender
            e.sid = item.sid
            e.time = formatDate(new Date(item.created))
            e.like = item.like
            e.dislike = item.dislike
            e.content = item.content
            e.action = item.userLikeOp
            e.canDelete = item.sid === curUid.value
            e.canDelete = curUid.value === 2 || e.canDelete
            dataSource.value.push(e)
          })
          if (data.length === 0 || data.length < count) {
            offset = -1
          } else {
            offset += data.length
          }
          cursor.set(pid, offset as number)
        })
    }

    const loadReply = (idx:number) => {
      const cursor = conversationLoadCursor.value
      const item = dataSource.value[idx]
      let offset = cursor.get(item.id)
      if (offset !== undefined) {
        if (offset === -1) {
          message.info('已经加载所有回复', 0.4)
          return
        }
      } else {
        offset = 0
      }
      item.replyLoadStatus = true
      const batch = 5
      getConversation(item.id, offset, batch)
        .then(response => {
          if (response.status !== 200) {
            message.info('请求错误')
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            return
          }
          const conn = conversations.value.get(item.id)
          let tmp:CommentDs[] = []
          if (conn !== undefined) {
            tmp = conn
          }
          resp.data.forEach((item:any) => {
            const e = createCommentDs()
            e.id = item.id
            e.sender = item.sender
            e.receiver = item.receiver
            e.rid = item.rid
            e.sid = item.sid
            e.time = formatDate(new Date(item.created))
            e.like = item.like
            e.dislike = item.dislike
            e.content = item.content
            e.action = item.userLikeOp
            e.canDelete = item.sid === curUid.value
            e.canDelete = curUid.value === 2 || e.canDelete
            tmp.push(e)
          })
          if (resp.data.length === 0 || resp.data.length < batch) {
            cursor.set(item.id, -1)
          } else {
            offset += resp.data.length
            cursor.set(item.id, offset as number)
          }
          conversations.value.set(idx, tmp)
          item.replyLoadStatus = false
          // setTimeout(() => { item.replyLoadStatus = false }, 1000)
        })
    }

    const onDeleteReply = (id: number, idx: number, cid: number) => {
      deleteComment(id)
        .then((response) => {
          if (response.status !== 200) {
            message.info('请求出错')
            return
          }
          const resp = response.data
          if (resp.code !== 0 || resp.data === null) {
            message.info('返回出错')
            return
          }
          if (resp.data) {
            const c = conversations.value
            const conn = c.get(cid)
            if (conn !== undefined) {
              conn.splice(idx, 1)
            }
          } else {
            message.info('删除出错')
          }
        })
    }

    watch(() => props.pid, (curPid, prePid) => {
      if (curPid !== prePid) {
        dataSource.value.length = 0
        conversations.value.clear()
        conversationLoadCursor.value.clear()
        commentLoadCursor.value.clear()
      }
    })

    onMounted(() => {
      curUid.value = getUserID()
    })
    return {
      dataSource,
      conversations,
      comment,
      reply,
      dislike,
      like,
      spanReply,
      spanConversation,
      submitComment,
      onDeleteComment,
      submitReply,
      loadReply,
      onDeleteReply,
      submitInnerReply,
      loadQusComment
    }
  }
})
</script>

<style scoped>

</style>
